home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
motif
/
otessellate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
11KB
|
415 lines
/*
* Copyright (c) 1993-94, Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the name of Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
* POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
/*----------------------------------------------------------------------------
*
* otessellate.c : openGL (motif) example showing how to tessellate
* concave polygons and polygons with holes
*
* Author : Yusuf Attarwala
* SGI - Applications
* Date : Sep 93
*
* press left button for animation
* press middle button to turn OFF tessellation
* press right button to turn ON tessellation
*
*---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Xm/Xm.h>
#include <Xm/Frame.h> /* for frame widgets */
#include <Xm/Form.h> /* for form widgets */
#include <X11/keysym.h> /* keyboard translations */
#include <X11/StringDefs.h>
#include <GL/gl.h> /* gl includes */
#include <GL/glu.h> /* utility library includes */
#include <GL/GLwMDrawA.h> /* include for the drawing area widget */
static int tessellationOn = 0;
/* function declarations */
void
createToplevel(void),
drawScene(void),
setMatrix(void),
animation(void),
doTessellation(void),
exposeCB(Widget,XtPointer,XtPointer),
resizeCB(Widget,XtPointer,XtPointer),
initCB(Widget,XtPointer,XtPointer),
inputCB(Widget,XtPointer,XtPointer);
/* callback functions for tessellator */
void
myBegin(GLenum),
myVertex(void *),
myEnd(void),
myError(GLenum);
/* global variables */
Display *display; /* current display */
XtAppContext appContext; /* X application context */
float ax,ay,az; /* angles for animation */
Widget toplevel, /* toplevel shell */
glw; /* current widget */
GLXContext glxc; /* current glx context */
Arg args[20];
int acnt;
/* coords of outer star */
static GLfloat outerColor[3] = {1.0,1.0,0.0};
static int nouter = 10;
static GLfloat outer[10][3] = {3.5,5.0,0.0,
2.0,2.0,0.0,
5.0,4.0,0.0,
8.0,2.0,0.0,
6.5,5.0,0.0,
8.0,6.0,0.0,
6.0,6.0,0.0,
5.0,8.0,0.0,
4.0,6.0,0.0,
2.0,6.0,0.0};
/* coords of inner star */
static int ninner = 10;
static GLfloat inner[10][3] = {3.8,5.0,0.0,
2.6,2.6,0.0,
5.0,4.2,0.0,
7.4,2.6,0.0,
6.2,5.0,0.0,
7.4,5.8,0.0,
5.8,5.8,0.0,
5.0,7.4,0.0,
4.2,5.8,0.0,
2.6,5.8,0.0};
/* display list identifier */
GLuint tList = 1;
void
main(int argc, char** argv)
{
XtToolkitInitialize();
appContext = XtCreateApplicationContext();
display = XtOpenDisplay(appContext, NULL, "Otessellate","otessellate",NULL,0,
&argc,argv);
if (!display) {
printf("%s : Unable to open display\n",argv[0]);
exit(0);
}
printf("\n---------------------------------------------\n");
printf("OpenGL tessellation example \n\n");
printf("Press: left button for animation\n\
middle button to turn OFF tessellation (default)\n\
right button to turn ON tessellation \n");
createToplevel(); /* create widget hierarchy */
XtAppMainLoop(appContext); /* loop forever */
}
void
createToplevel(void)
{
Widget frame;
acnt = 0;
XtSetArg(args[acnt],XmNminHeight, 300);acnt++;
XtSetArg(args[acnt],XmNminWidth, 300);acnt++;
XtSetArg(args[acnt],XmNminAspectX, 1);acnt++;
XtSetArg(args[acnt],XmNminAspectY, 1);acnt++;
XtSetArg(args[acnt],XmNmaxAspectX, 1);acnt++;
XtSetArg(args[acnt],XmNmaxAspectY, 1);acnt++;
toplevel = XtAppCreateShell("openGL tessellate","otessellate",
applicationShellWidgetClass,
display,args,acnt);
/* create a frame to hold glx widget */
frame = XtVaCreateManagedWidget("frame",
xmFrameWidgetClass, toplevel,
NULL);
/* create a double buffer widget, in rgb mode and manage it */
acnt = 0;
XtSetArg(args[acnt], GLwNrgba, TRUE); acnt++;
XtSetArg(args[acnt], GLwNdoublebuffer, TRUE); acnt++;
XtSetArg(args[acnt], GLwNallocateBackground, TRUE); acnt++;
glw = GLwCreateMDrawingArea(frame, "glw", args, acnt);
XtManageChild(glw);
/* register callbacks */
XtAddCallback(glw, GLwNginitCallback, initCB, NULL);
/* realize widget hierarchy */
XtRealizeWidget(toplevel);
/* additional callbacks */
XtAddCallback(glw, GLwNexposeCallback, exposeCB, NULL);
XtAddCallback(glw, GLwNresizeCallback, resizeCB, NULL);
XtAddCallback(glw, GLwNinputCallback, inputCB, NULL);
}
void
drawScene(void)
{
int i;
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(4.0,4.0,0.0);
glRotatef (ax,1.0,0.0,0.0);
glRotatef (-ay,0.0, 1.0, 0.0);
glRotatef (az,0.0, 0.0, 1.0);
glTranslatef(-4.0,-4.0,0.0);
/* all the good stuff follows */
if (tessellationOn) {
/* draw the tessellated polygons (stored in display list) */
glCallList(tList);
}
else {
/* draw the original polygons */
glColor3fv(outerColor);
glBegin(GL_LINE_LOOP);
for (i=0;i<nouter;i++) {
glVertex3fv((GLfloat *)outer[i]);
}
glEnd();
glBegin(GL_LINE_LOOP);
for (i=0;i<ninner;i++) {
glVertex3fv((GLfloat *)inner[i]);
}
glEnd();
}
/* end of good stuff */
glPopMatrix();
glFlush();
glXSwapBuffers(XtDisplay(glw), XtWindow(glw));
}
void
setMatrix(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-0.5,9.5,-0.5,9.5,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void
animation(void)
{
register int i;
/* animate the star */
for (i=0;i<60;i++) {
/*
ax += 1.5;
ay -= 2.5;
*/
az += 3.0;
if (ax >= 360) ax = 0.0;
if (ay <= -360) ay = 0.0;
if (az >= 360) az = 0.0;
drawScene();
}
}
void
inputCB(Widget w, XtPointer client_data, XtPointer call)
{
static int firstTime = 1;
char string[31];
XComposeStatus composeStatus;
KeySym keysym;
GLwDrawingAreaCallbackStruct *call_data;
call_data = (GLwDrawingAreaCallbackStruct *) call;
switch(call_data->event->type) {
case ButtonPress:
switch (call_data->event->xbutton.button) {
case Button1:
animation();
break;
case Button2 :
tessellationOn = 0;
XtVaSetValues(toplevel,XmNtitle, "No Tessellation",NULL);
drawScene();
break;
case Button3 :
tessellationOn = 1;
if (firstTime) {
firstTime = 0;
doTessellation();
}
XtVaSetValues(toplevel,XmNtitle, "Tessellated Polygons",NULL);
drawScene();
break;
}
break;
case KeyPress :
XLookupString((XKeyEvent *)call_data->event,string,
30,&keysym,&composeStatus);
switch(keysym) {
case XK_Escape :
exit(0);
break;
}
break;
default:
break;
}
}
void
resizeCB(Widget w, XtPointer client_data, XtPointer call)
{
GLwDrawingAreaCallbackStruct *call_data;
call_data = (GLwDrawingAreaCallbackStruct *) call;
GLwDrawingAreaMakeCurrent(w, glxc);
glViewport(0, 0, call_data->width, call_data->height);
setMatrix();
drawScene();
}
void
exposeCB(Widget w, XtPointer client_data, XtPointer call)
{
GLwDrawingAreaCallbackStruct *call_data;
call_data = (GLwDrawingAreaCallbackStruct *) call;
GLwDrawingAreaMakeCurrent(w, glxc);
glViewport(0, 0, call_data->width, call_data->height);
drawScene();
}
void
initCB(Widget w, XtPointer client_data, XtPointer call)
{
XVisualInfo *vi;
XtSetArg(args[0], GLwNvisualInfo, &vi);
XtGetValues(w, args, 1);
glxc = glXCreateContext(XtDisplay(w), vi, 0, GL_TRUE);
ax = 10.0;
ay = -10.0;
az = 0.0;
}
void
doTessellation()
{
int i;
GLUtriangulatorObj *tobj;
GLdouble db3[3];
/* create a tessellation object */
tobj = gluNewTess();
/* register callbacks */
gluTessCallback(tobj,GLU_BEGIN, myBegin);
gluTessCallback(tobj,GLU_VERTEX,myVertex);
gluTessCallback(tobj,GLU_END, myEnd);
gluTessCallback(tobj,GLU_ERROR, myError);
glNewList(tList,GL_COMPILE);
glColor3fv(outerColor);
gluBeginPolygon(tobj);
for (i=0;i<nouter;i++) {
db3[0] = (GLdouble) outer[i][0];
db3[1] = (GLdouble) outer[i][1];
db3[2] = (GLdouble) outer[i][2];
gluTessVertex(tobj,(GLdouble *)db3,(void *)outer[i]);
}
gluNextContour(tobj,GLU_INTERIOR);
for (i=0;i<ninner;i++) {
db3[0] = (GLdouble) inner[i][0];
db3[1] = (GLdouble) inner[i][1];
db3[2] = (GLdouble) inner[i][2];
gluTessVertex(tobj,(GLdouble *)db3,(void *)inner[i]);
}
gluEndPolygon(tobj);
glEndList();
/* free the tess obj, when done */
gluDeleteTess(tobj);
}
void
myBegin(type)
GLenum type;
{
glBegin(type);
}
void
myVertex(data)
void *data;
{
glVertex3fv((GLfloat *)data);
}
void
myEnd()
{
glEnd();
}
void
myError(errnum)
GLenum errnum;
{
printf("myError %s \n",gluErrorString(errnum));
}